import {messages} from "share/common";
import React from 'react';
import {Modal, Table, Select, Checkbox, Alert, Spin, message} from 'antd';
import CostCenterSearchFormService from 'components/template/cost-center-search-form/cost-center-search-form.service';
import debounce from 'lodash.debounce';
import 'styles/components/search-area.scss'

class CostCenterSearchForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false,
      costCenters: [],
      data: [],
      columns: [
        {
          title: messages('components.key438'/*成本中心名称*/),
          key: 'costCenterOid',
          dataIndex: 'costCenterOid',
          render: (value, item) => {
            return this.renderName(item)
          }
        }, {
          title: messages('components.key439'/*全部项*/),
          key: 'isAll',
          width: '100px',
          dataIndex: 'isAll',
          render: (value, item) => {
            return this.renderIsAll(item)
          }
        }, {
          title: messages('components.key440'/*成本中心项从*/),
          key: 'costCenterItemCodeFrom',
          dataIndex: 'costCenterItemCodeFrom',
          render: (value, item) => {
            return this.renderSearchInput(item, 'costCenterItemCodeFrom')
          }
        }, {
          title: messages('components.key441'/*成本中心项至*/),
          key: 'costCenterItemCodeTo',
          dataIndex: 'costCenterItemCodeTo',
          render: (value, item) => {
            return this.renderSearchInput(item, 'costCenterItemCodeTo')
          }
        }
      ],
      loading: false
    };
    this.lastValue = null;
    this.fetched = false;
    this.getCodeOptions = debounce(this.getCodeOptions, 300);
  }

  componentWillMount() {
    this.setState({loading: true});
    CostCenterSearchFormService.getCostCenters().then(res => {
      this.setState({costCenters: res.data, loading: false}, () => {
        this.fetched = true;
        this.initialAll(this.lastValue || res.data, []);
      })
    }).catch(e => {
      this.setState({loading: false});
      message.error(e.response.data.message);
    });
  }

  componentWillReceiveProps(nextProps) {
    /**
     * 原本这里是直接initData的
     * 但是这个情况下，如果willMount里面的接口没有跑完，下面的initData里就会报错，因为constCenters还是空数组
     * 所以这里借助了fetched和lastValue两个值进行控制
     * 只有上面的接口跑完了，才能initData，否则就把最新的值压进lastValue，接口跑通后自动处理
     * 这样保证接口只调了一次而且还进行了顺序控制
     */
    if(this.fetched) {
      this.initData(nextProps.value);
    } else {
      this.lastValue = nextProps.value;
    }
  }

  initialAll = (arr, value) => {
    let data = [];
    this.getValidData(arr).forEach((item, index) => {
      data.push({
        id: index,
        costCenterID: item.id,
        costCenterOid: undefined,
        isAll: false,
        costCenterItemCodeFrom: '',
        costCenterItemCodeTo: '',
        options: [],
        fromCodeOptions: [],
        toCodeOptions: []
      })
    });
    this.setState({data}, () => {
      this.initData(value);
    });
  };

  // 可输入项长度
  getValidData = (data) => {
    const {length} = this.props;
    return data.slice(0, length)

  };
  // 初始化表单数据
  initData = (value) => {
    const {costCenters} = this.state;
    const { type } = this.props;
    let data = [];
    Array.isArray(costCenters) && (
      this.getValidData(costCenters).forEach((item, index) => {
        data.push({
          id: index,
          costCenterID: item.id,
          costCenterOid: undefined,
          isAll: false,
          costCenterItemCodeFrom: '',
          costCenterItemCodeTo: '',
          options: [],
          fromCodeOptions: [],
          toCodeOptions: []
        })
      })
    );
    if(value && Array.isArray(value)){
      if(type === 'oid'){
        this.getValidData(value).forEach((val, index) => {
          data[index].costCenterOid = val.costCenterOid;
          data[index].isAll = !val.costCenterItemCodeFrom && !val.costCenterItemCodeTo;
          data[index].costCenterItemCodeFrom = val.costCenterItemCodeFrom;
          data[index].costCenterItemCodeTo = val.costCenterItemCodeTo;
          data[index].options = costCenters.filter(item => item.costCenterOID === val.costCenterOid);
        })
      } else {
        this.getValidData(value).forEach((val, index) => {
          data[index].costCenterOid = costCenters.filter(item => item.id === val.costCenterID)[0].costCenterOID;
          data[index].isAll = !val.fromCode && !val.toCode;
          data[index].costCenterItemCodeFrom = val.fromCode;
          data[index].costCenterItemCodeTo = val.toCode;
          data[index].options = costCenters.filter(item => item.id === val.costCenterID);
        })
      }
    }
    this.setState({data});
  };
  // 获取搜索条件
  getParams = ({item, value, key}) => {
    let params = {
      page: 0,
      size: 20,
      keyword: value
    };
    if (key === 'costCenterItemCodeFrom') {
      item.costCenterItemCodeTo && (params.toCode = item.costCenterItemCodeTo);
      return params;
    }
    if (key === 'costCenterItemCodeTo') {
      item.costCenterItemCodeFrom && (params.fromCode = item.costCenterItemCodeFrom);
      return params;
    }
  };
  // 改变code
  changeCode = ({value, item, key}) => {
    item[key] = value;
    if (!value) {
      item[this.getCurrentCodeOptionKey(key)] = [];
      this.setState({data: this.state.data});
      return !1;
    }
    const currentOption = [...item[this.getCurrentCodeOptionKey(key)]].filter(option => option.name === value)[0];
    currentOption && (item[key] = value = currentOption.code);
    this.setState({data: this.state.data});
    item.isAll = false;
    this.getCodeOptions({value, item, key});
  };
  // 获取对应的code项的值列表的key
  getCurrentCodeOptionKey = (key) => {
    return key === 'costCenterItemCodeTo' ? 'toCodeOptions' : 'fromCodeOptions';
  };
  // 失去焦点处理
  onBlur = (item, key) => {
    if (![...item[this.getCurrentCodeOptionKey(key)]].some(option => option.code === item[key])) {
      this.changeCode({value: undefined, item, key});
    }
  };
  // 获取成本中心项选择项
  getCodeOptions = ({item, value, key}) => {
    if (!item.costCenterOid) {
      this.setState({data: this.state.data});
      return !1;
    }
    CostCenterSearchFormService.getCostCenterItems(item.costCenterOid, this.getParams({item, value, key})).then(res => {
      let data = res.data;
      data.forEach(item => {
        item.name = `${item.code}-${item.name}`
      });
      item[this.getCurrentCodeOptionKey(key)] = data;
      this.setState({data: this.state.data});
    })
  };
  // 搜索输入框
  renderSearchInput = (item, key) => {
    return (<Select
      allowClear
      showSearch
      mode='combobox'
      value={item[key]}
      style={{width: '100%'}}
      optionFilterProp='children'
      placeholder={messages('components.key442'/*请输入代码or名称*/)}
      onChange={(value) => this.changeCode({value, item, key})}
      onBlur={() => {this.onBlur(item, key)}}
      onFocus={() => this.changeCode({value: item[key], item, key})}
      getPopupContainer={triggerNode => triggerNode.parentNode}
    >
      {item[[this.getCurrentCodeOptionKey(key)]].map((option) => {
        return <Select.Option key={option.name}>{option.name}</Select.Option>
      })}
    </Select>);
  };
  // 改变全选框
  changeIsAll = (e, item) => {
    item.isAll = e.target.checked;
    item.costCenterItemCodeFrom = '';
    item.costCenterItemCodeTo = '';
    item.fromCodeOptions = [];
    item.toCodeOptions = [];
    this.setState({data: this.state.data});
  };
  // 全选项框
  renderIsAll = (item) => {
    return (<Checkbox onChange={(e) => this.changeIsAll(e, item)} checked={item.isAll}></Checkbox>)
  };
  // 获取成本中心名称选择项
  getOptions = (item) => {
    const {costCenters, data} = this.state;
    let options = [];
    costCenters.forEach(costCenter => {
      if (!data.some(val => val.costCenterOid === costCenter.costCenterOID) || costCenter.costCenterOID === item.costCenterOid) {
        options.push(costCenter);
      }
    });
    item.options = options;
    this.setState({data: this.state.data});
  };
  // 改变成本中心名称
  changeName = (value, item) => {
    item.costCenterOid = value;
    item.isAll = !!value;
    item.codeOptions = [];
    item.costCenterItemCodeFrom = '';
    item.costCenterItemCodeTo = '';
    this.setState({data: this.state.data});
  };
  // name 渲染
  renderName = (item) => {
    return (<Select placeholder={messages('common.please.select')}
                    value={item.costCenterOid}
                    onChange={(value) => this.changeName(value, item)}
                    allowClear
                    style={{width: '100%'}}
                    onFocus={() => this.getOptions(item)}
                    getPopupContainer={triggerNode => triggerNode.parentNode}
    >
      {item.options.map((option) => {
        return <Select.Option key={option.costCenterOID}>{option.name}</Select.Option>
      })}
    </Select>)
  };

  onOk = () => {
    const { data } = this.state;
    this.props.onChange(this.getResult(data));
    this.setState({showModal: false});
  };

  getResult = data => {
    const { type } = this.props;
    let result = [];
    data.map(item => {
      if(item.costCenterOid){
        type === 'oid' ? result.push({
          costCenterOid: item.costCenterOid,
          costCenterItemCodeFrom: item.costCenterItemCodeFrom,
          costCenterItemCodeTo: item.costCenterItemCodeTo,
        }) : result.push({
          costCenterID: item.costCenterID,
          fromCode: item.costCenterItemCodeFrom,
          toCode: item.costCenterItemCodeTo,
        });
      }
    });
    return result;
  };

  onCancel = () => {
    // this.props.onChange(this.props.value);
    this.setState({showModal: false});
  };

  render() {
    const { showModal, columns, data, loading } = this.state;
    const { title, placeholder } = this.props;
    const value = this.getResult(data);
    return (
      <Spin spinning={loading}>
        <div className='ant-input' style={{cursor: 'pointer'}} onClick={() => this.setState({showModal: true})}>
          {!value || value.length < 1 ? <span>{placeholder}</span> : messages('common.total.selected', {total: value.length})}
        </div>
        <Modal
          visible={showModal}
          title={title}
          okText={messages('common.ok')}
          cancelText={messages('common.cancel')}
          width={800}
          onOk={this.onOk}
          onCancel={this.onCancel}
          wrapClassName='cost-center-search-modal'
        >
          <Alert
            message={(<div>
              <p style={{margin: '0'}}>{messages('components.key443'/*1: 请先选择成本中心名称*/)}</p>
              <p style={{margin: '0'}}>{messages('components.key444'/*2: 成本中心项从的序号需 ≤ 成本中心项至的序号,否则搜索无结果*/)}</p>
            </div>)}
            key={'info'}
            type={'info'}
            showIcon/>
          <Table columns={columns}
                 rowKey='id'
                 pagination={false}
                 dataSource={data}/>
        </Modal>
      </Spin>
    )
  }
}

CostCenterSearchForm.propTypes = {
  type: React.PropTypes.string,
  placeholder: React.PropTypes.string,  //输入框空白时的显示文字
  title: React.PropTypes.string,  //弹窗标题
  length: React.PropTypes.number, // 可输入项长度
  value: React.PropTypes.array
};

CostCenterSearchForm.defaultProps = {
  type: 'oid',
  placeholder: messages('common.please.select'),
  title: '',
  length: 5,
  // value: []
};

export default CostCenterSearchForm;
